Skip to content

Get ready for physics benchmarks - #37

Open
mattleblanc wants to merge 1 commit into
mainfrom
benchmark-metrics
Open

Get ready for physics benchmarks#37
mattleblanc wants to merge 1 commit into
mainfrom
benchmark-metrics

Conversation

@mattleblanc

@mattleblanc mattleblanc commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

This PR adds a compact JSON metrics extractor for automated reconstruction validation.

The extractor reads one or more EDM4hep RECO files and records:

  • input checksums and production provenance;
  • event counts and collection availability;
  • truth-particle kinematics and PDG counts;
  • Pandora PFO multiplicity and nearest-PFO matching;
  • reconstructed energy and momentum response;
  • selected-track occupancy; and
  • ECAL/HCAL hit multiplicities and energies.

This PR intentionally does not define pass/fail tolerances. The initial metrics are report-only so that their statistical viability can be reviewed in the context of the CI worker limits.

Testing

  • Six ROOT-independent unit tests pass.
  • Successfully processed 100-event muon, electron, pion, and photon samples.
  • Validated inside the v3.1 Muon Collider simulation environment.
  • Combined four-species output is approximately 27 kB of JSON.

Follow-up

A subsequent mucoll-spack PR will run this code as part of a small GitHub Actions validation test, but that PR won't work until this one is merged. I can open it in advance if it's easier to review them together...

Copilot AI lite review requested due to automatic review settings August 19, 2026 00:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new reconstruction benchmarking utility under analysis/benchmarks that extracts a compact, machine-readable JSON summary from EDM4hep RECO ROOT files, intended for automated comparisons (e.g., CI artifacts and release-to-release validation).

Changes:

  • Added extract_metrics.py, a ROOT-based extractor that summarizes truth, PFO matching, track occupancy, and calorimeter hit/energy metrics into a compact JSON schema.
  • Added ROOT-independent unit tests for helper functions used by the extractor.
  • Added documentation for running the extractor and positioned the benchmarks tooling within the analysis directory structure.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
analysis/README.md Mentions the new benchmarks/ directory and its purpose.
analysis/benchmarks/README.md Documents extractor behavior, matching definition, and how to run tests.
analysis/benchmarks/extract_metrics.py Implements JSON metrics extraction from EDM4hep RECO files using PyROOT/RDataFrame + JIT helpers.
analysis/benchmarks/test_extract_metrics.py Adds ROOT-independent unit tests for parsing and stats/provenance helper functions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread analysis/benchmarks/extract_metrics.py
@mattleblanc

Copy link
Copy Markdown
Contributor Author

This is an example output of running this on a pion gun sample with 100 events:

{
  "schema_version": 1,
  "software": {
    "root_version": "6.38.00"
  },
  "configuration": {
    "match_delta_r_max": 0.1
  },
  "sample": {
    "label": "pion",
    "event_count": 100,
    "input": {
      "bytes": 69773173,
      "sha256": "61cb878093eed8057fbf61006c11f7838a00979a0c683f45b6e84133954fcee3"
    },
    "truth": {
      "pdg_counts": {
        "211": 100
      },
      "pt_gev": {
        "mean": 50.4865,
        "median": 55.2679,
        "p16": 16.7165,
        "p84": 84.7123
      }
    },
    "reconstruction": {
      "matched_events": 95,
      "matched_fraction": 0.95,
      "matched_energy_over_truth_energy": {
        "count": 95,
        "mean": 0.9201,
        "median": 0.9994,
        "p16": 0.9478,
        "p84": 1.0050
      },
      "pfo_multiplicity": {
        "mean": 3.49,
        "median": 2,
        "min": 1,
        "max": 18
      },
      "events_with_selected_track": 70,
      "events_with_selected_track_fraction": 0.70,
      "ecal_hit_multiplicity": {
        "mean": 1114.52,
        "median": 999.5
      },
      "hcal_hit_multiplicity": {
        "mean": 253.03,
        "median": 181.5
      }
    }
  }
}

"path": str(pathlib.Path(__file__).resolve()),
"sha256": sha256(pathlib.Path(__file__).resolve()),
},
"software": {"root_version": str(ROOT.gROOT.GetVersion())},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this extract the mucoll-stack version instead of ROOT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a good idea.

@madbaron

Copy link
Copy Markdown
Contributor

I am wondering a little bit about the metric extraction strategy: would it be cleaner to have a central helper for the deltaR matching, and actually compute all metrics in the various "study_muons.py" etc, so that each independently produces and object-specific json and the script here just aggregates whatever is available at the end?

@madbaron

Copy link
Copy Markdown
Contributor

Another point for discussion: I think are are reasons to wire this up both in MAIAConfig (etc) and at the end of the physval in mucoll-spack.

Is this what you were planning to do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants